﻿using System;
using SharpStockLib.Fin;
using SharpStockLib.Data;
using SharpBackTestLib.Orders;

namespace SharpBackTestLib.Strategies
{
    /// <summary>
    /// Simple basic strategy based on two Simple Moving Averages. The signals are the following :
    /// * buy when price closes above the short-period SMA and short-period SMA &gt; long-period SMA. Cover when price closes below short-period SMA.
    /// * sell short when price closes below the short-period SMA and short-period SMA &lt; long-period SMA. Cover when price closes above short-period SMA.
    /// </summary>
    public class SMACrossoverStrategy
    {
        private readonly int _periodShort;
        private readonly int _periodLong;
        private readonly IInstrument _instrument;
        private readonly SMACrossoverSignalManager _signalMgr;

        public event EventHandler<EntrySignalEventArgs> EntrySignal;
        public event EventHandler<ExitSignalEventArgs> ExitSignal;

        /// <summary>
        /// Constructor. Needs the values of the periods of the moving averages.
        /// </summary>
        /// <param name="instrument">The instrument this strategy will apply to.</param>
        /// <param name="periodShort">Value of the period of the short-term SMA.</param>
        /// <param name="periodLong">Value of the period of the long-term SMA.</param>
        public SMACrossoverStrategy(IInstrument instrument, int periodShort, int periodLong)
        {
            _periodLong = periodLong;
            _periodShort = periodShort;
            _instrument = instrument;
            _signalMgr = new SMACrossoverSignalManager(_periodShort, _periodLong);
        }

        /// <summary>
        /// Updates indicators and sends buy/sell signals when needed to the position manager
        /// </summary>
        /// <param name="data">The actual price data</param>
        public void OnNewData(IData data)
        {
            ESignalType signal = _signalMgr.OnNewData(data);
            
            // Sends events for pos manager
            if (signal == ESignalType.Buy || signal == ESignalType.Sell)
            {
                if (EntrySignal != null)
                    EntrySignal(this, new EntrySignalEventArgs(new EntrySignal(signal, data, _instrument)));
            }
            else if (signal == ESignalType.CoverBuy || signal == ESignalType.CoverSell)
            {
                if (ExitSignal != null)
                    ExitSignal(this, new ExitSignalEventArgs(new ExitSignal(signal, data, _instrument)));
            }
        }
    }
}
